package br.great.clientServer;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import br.great.config.GetCheminServer;
import br.great.classes.TradeImage;
import br.great.DAO.*;
import br.great.beans.*;
import br.great.functionalCore.FileSender;
import br.great.functionalCore.TagIndexCreator;
import br.great.typeTags.Type_Tags;

/**
 * PhotoMap
 * Copyright (c) 2007-2008 STEAMER - LIG, All rights reserved.
 */ 
/**
 * @author Developpement of PhotoMap
 */
public class PhotoSender {

    private static volatile PhotoSender instace_PhotoSender = new PhotoSender();
    private double weight = 1;
    DAO_Multimedia dm = DAO_Multimedia.getInstance();
    DAO_AnnotationPhotoInfo dapi = DAO_AnnotationPhotoInfo.getInstance();
    DAO_Photo dp = DAO_Photo.getInstance();
    DAO_Wiki dw = DAO_Wiki.getInstance();
    DAO_ContentAnnotation dca = DAO_ContentAnnotation.getInstance();
    DAO_TAG dt = DAO_TAG.getInstance();
    DAO_ContentAnnotationHasTag dcah = DAO_ContentAnnotationHasTag.getInstance();
    DAO_InvertedIndexHasPhoto diihp = DAO_InvertedIndexHasPhoto.getInstance();
    DAO_PhotoHasContentAnnotation dcaca = DAO_PhotoHasContentAnnotation.getInstance();
    DAO_CollectionHasMultimedia dchm = DAO_CollectionHasMultimedia.getInstance();
    DAO_InvertedIndex dii = DAO_InvertedIndex.getInstance();
    DAO_Inverted_Extended_Index diei= DAO_Inverted_Extended_Index.getInstance();

    /** The private constructor of  PhotoSender for singleton
     */
    private PhotoSender() {
    }

    /** The method for get the instance of the class  PhotoSender
     * @return  PhotoSender instace PhotoSender
     */
    public static PhotoSender getInstance() {
        //if(instace PhotoSender==null)
        synchronized (PhotoSender.class) {
            if (instace_PhotoSender == null) {
                instace_PhotoSender = new PhotoSender();
            }
        }
        return instace_PhotoSender;
    }

    private Vector sendPhoto(Photo photo, String nameCollection, String loginUser) {

      /*
        //pHOTO FLICKR
        float[] fa = new float[2];
        fa[0]=200;
        fa[1]=200; //width of min photo
        Vector v = new Vector();
        
        v.add(photo.getURIPhoto());
        v.add(fa);
        return v;
        */
      
    // photos locale
     String toPath = GetCheminServer.serverfileAddress + "photos\\" + loginUser + "\\" + nameCollection + "\\";
        String toPhoto = toPath + photo.getUniqID() + ".jpg";
        String toPhotoOwl = toPath + photo.getUniqID() + ".owl";
        String toPhotoMini = photo.getUniqID() + "_mini";
        float[] fa = new float[2];
        Vector v = new Vector();
        try {
            String fromPhotoPath = photo.getURIPhoto();
            TradeImage ti = new TradeImage();
            fa = ti.createThumbnail(fromPhotoPath, toPath, toPhotoMini);
            FileSender.senderFile(fromPhotoPath, toPhoto);
            FileSender.senderFile(fromPhotoPath.replace(".jpg",".owl"),toPhotoOwl);
        } catch (Exception ex) {
            Logger.getLogger(PhotoSender.class.getName()).log(Level.SEVERE, null, ex);
        }
        v.add("photos/" + loginUser + "/" + nameCollection + "/" + photo.getUniqID() + ".jpg");
        v.add(fa);
        return v;
    }

    public boolean insertPhotos(Collection collection, Photo photo, br.great.beans.Address address, User user) {
        System.out.println("Begin of photo insertion");
        TagIndexCreator tagIndex = new TagIndexCreator();
        // send photo
        Vector vURIPhoto = sendPhoto(photo, collection.getName(), user.getLogin());
        photo.setURIPhoto((String) vURIPhoto.get(0));
       // System.out.println ("insert photo: "+photo.getURIPhoto());
        photo.setLength_width((float[]) vURIPhoto.get(1));

        photo.setURIAnnotations("photos/" + user.getLogin() + "/" + collection.getName() + "/" + photo.getUniqID() + ".owl");

        // insert into multimedia 
        Multimedia multimedia = new Multimedia();
        multimedia.setTYPE("photo");
        int idMultimedia = dm.insertMultimedia(multimedia);

        // insert into AnnotationPhotoInfo
        AnnotationPhotoInfo api = new AnnotationPhotoInfo();

        Calendar cal = Calendar.getInstance();
        if (photo.getDateTime() != null) {
            cal.setTime(photo.getDateTime());
        }

        api.setID_DAYS(cal.get(Calendar.DAY_OF_WEEK));
        api.setID_YEARS(cal.get(Calendar.YEAR) - 1900);
        api.setID_MONTHS(cal.get(Calendar.MONTH));
        if (photo.getDateTime() != null) {
            api.setDAYTIME(new Timestamp(photo.getDateTime().getTime()));
        }
        api.setSEASON(photo.getSeason());
        api.setNAME_CITY(address.getNameCity());
        api.setNAME_COUNTRY(address.getNameCountry());
//        api.setNAME_ROAD(address.getNameRoad());
        api.setPART_OF_DAY(photo.getPartOfDay());
        api.setVALUE(photo.getTemperature().getValue());
        api.setWEATHER(photo.getWeather().getDescription());
        api.setWEATHER_ICONS(photo.getWeather().getURLPhoto());

        int[] intB = dapi.insertAnnotationPhotoInfo(api);

        // inser into Content Annotation
        Photo_ContentAnnotation pca = new Photo_ContentAnnotation();
        pca.setPHRASE(photo.getContentAnnotation());
        int iCA = dca.insertAnnotation(pca);

        // insert into TAG, ContentAnnotation, ContentAnnotationHasTag, PHOTO_has_CONTENT_ANNOTATION
        Vector vTag = photo.getTags();
        weight = 1;
        for (int iTag = 0; iTag < vTag.size(); iTag++) {
            Tag t = (Tag) vTag.elementAt(iTag);
            if (!t.getTAG_VALUE().contains("null")) {
                t.setTAG_TYPE(new Type_Tags().getManuel());
                t.setTAG_SUB_TYPE(new Type_Tags().getManuel());
                t.setTAG_ID(dt.insertTAG(t));
                dcah.insertContentAnnotationHasTag(t.getTAG_ID(), iCA, weight);
            }
        }
       

        // insert into Photos
        dp.insertPhoto(photo, address, idMultimedia, intB[0], intB[1], intB[2], intB[3]);
        // insert the values in ContentAnnotationHasTag
        dcaca.insertPhotoHasContentAnnotation(idMultimedia, iCA);
        
        
        // insert into Wikis
        Vector vWiki = photo.getNearByWikiObject();
        if (vWiki != null) {
            for (int iWiki = 0; iWiki < vWiki.size(); iWiki++) {
                Wiki wiki = (Wiki) vWiki.elementAt(iWiki);
                if(iWiki <5){ // prends le 5 plus proche
                dw.insertWiki(idMultimedia, wiki);
                }
            }
        }
        // insert the values in CollectionHasMultimedia
        dchm.insertCollectionHasMultimedia(idMultimedia, collection.getID_Collection());

        
         //insert Manual Tags as invertedIndex
        InvertedIndex iv = new InvertedIndex();
        weight = 1;
        for (int iTag = 0; iTag < vTag.size(); iTag++) {
            Tag t = (Tag) vTag.elementAt(iTag);
            if (!t.getTAG_VALUE().contains("null")) {
                iv.setTAG_VALUE(t.getTAG_VALUE());
//System.out.println(t.getTAG_VALUE());
                iv.setTAG_TYPE(new Type_Tags().getManuel());
                iv.setTAG_SUB_TYPE(new Type_Tags().getManuel());
                iv.setTAG_ID(dii.insertInvertedIndex(iv,tagIndex.getManualTag("")));
                diihp.insertInvertedIndexPhoto(iv.getTAG_ID(), idMultimedia, weight);
            }
        }

        Type_Tags tt = new Type_Tags();
        // insert the information of wiki in Tag
        if ((vWiki != null) && !vWiki.isEmpty()) {
            int iWiki=0;
            for (Object wiki : vWiki) {
                Wiki w = (Wiki) wiki;
                iWiki++;
               if(iWiki <5){ // prends le 5 plus proche
                if (w.getDistance() < 0.3) { //Seulement les wiki � 300 meter vont �tre de tag
                    double tagw = (1 / (1 + w.getDistance()));
                    if (!w.getTitle().equals("")) {
                        insertSeveralInfoInTags(iCA, w.getTitle(), tt.getLocation().nearObject.getTypeOfTAG(), tt.getLocation().nearObject.getSubTypeOfTAG(), tagw);
                        insertSeveralInvertedIndex(idMultimedia, w.getTitle(), tt.getLocation().nearObject.getTypeOfTAG(), tt.getLocation().nearObject.getSubTypeOfTAG(),tagw, tagIndex.getWikipediaTag(""));
                    }
                }
               } 
            }
        }
        // insert the information of Year in Tag
        if (!(cal.get(Calendar.YEAR) + "").equals("")) {
            insertSeveralInfoInTags(iCA, cal.get(Calendar.YEAR) + "", tt.getTemporal().year.getTypeOfTAG(),tt.getTemporal().year.getSubTypeOfTAG(), weight);
            insertSeveralInvertedIndex(idMultimedia, cal.get(Calendar.YEAR) + "", tt.getTemporal().year.getTypeOfTAG(),tt.getTemporal().year.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }
        // insert the information of Month in Tag
        if (!((new SimpleDateFormat("MMMMMMM", Locale.ENGLISH)).format(cal.getTime())).equals("")) {
            insertSeveralInfoInTags(iCA, (new SimpleDateFormat("MMMMMMM", Locale.ENGLISH)).format(cal.getTime()), tt.getTemporal().month.getTypeOfTAG(),tt.getTemporal().month.getSubTypeOfTAG(), weight);
            insertSeveralInvertedIndex(idMultimedia, (new SimpleDateFormat("MMMMMMM", Locale.ENGLISH)).format(cal.getTime()), tt.getTemporal().month.getTypeOfTAG(),tt.getTemporal().month.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }
        // insert the information of DayOfWeek in Tag
        if (!(new SimpleDateFormat("EEEEEEE", Locale.ENGLISH)).format(cal.getTime()).equals("")) {
            insertSeveralInfoInTags(iCA, (new SimpleDateFormat("EEEEEEE", Locale.ENGLISH)).format(cal.getTime()), tt.getTemporal().day.getTypeOfTAG(), tt.getTemporal().day.getSubTypeOfTAG(), weight);
            insertSeveralInvertedIndex(idMultimedia, (new SimpleDateFormat("EEEEEEE", Locale.ENGLISH)).format(cal.getTime()), tt.getTemporal().day.getTypeOfTAG(),tt.getTemporal().day.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }
        if (!(cal.get(Calendar.DAY_OF_MONTH) + "").equals("")) {
            insertSeveralInfoInTags(iCA, cal.get(Calendar.DAY_OF_MONTH) + "th_day", tt.getTemporal().day.getTypeOfTAG(),tt.getTemporal().day.getSubTypeOfTAG() ,weight);
            insertSeveralInvertedIndex(idMultimedia, cal.get(Calendar.DAY_OF_MONTH) + "th_day", tt.getTemporal().day.getTypeOfTAG(),tt.getTemporal().day.getSubTypeOfTAG() , weight, tagIndex.getTimeTag(""));
        }
        // insert the information of Weather in Tag
        //insertSeveralInfoInTags(iCA,photo.getWeather().getDescription());
        // insert the information of Season in Tag
        if (!photo.getSeason().equals("")) {
            insertSeveralInfoInTags(iCA, photo.getSeason(), tt.getTemporal().season.getTypeOfTAG(),tt.getTemporal().season.getSubTypeOfTAG(),weight);
            insertSeveralInvertedIndex(idMultimedia, photo.getSeason(), tt.getTemporal().season.getTypeOfTAG(), tt.getTemporal().season.getSubTypeOfTAG(),weight, tagIndex.getTimeTag(""));
        }
        // insert the country which we take the Photo in Tag
//        String countryCode = address.getNameCountry();
//        String countryName = dapi.getNameCountry(countryCode);  
        if(address!=null){            
            if (!address.getNameCountry().equals("")) {
                insertSeveralInfoInTags(iCA, address.getNameCountry(), tt.getLocation().country.getTypeOfTAG(), tt.getLocation().country.getSubTypeOfTAG(), weight);
                insertSeveralInvertedIndex(idMultimedia, address.getNameCountry(), tt.getLocation().country.getTypeOfTAG(),tt.getLocation().country.getSubTypeOfTAG(), weight, tagIndex.getAddressTag(""));
            }
            // insert the city which we take the Photo in Tag
            if (!address.getNameCity().equals("")) {
                insertSeveralInfoInTags(iCA, address.getNameCity(), tt.getLocation().city.getTypeOfTAG(),tt.getLocation().city.getSubTypeOfTAG(),weight);
                insertSeveralInvertedIndex(idMultimedia, address.getNameCity(), tt.getLocation().city.getTypeOfTAG(),tt.getLocation().city.getSubTypeOfTAG(), weight, tagIndex.getAddressTag(""));
            }
        }   
        // insert the road which we take the Photo in Tag
//        insertSeveralInfoInTags(iCA, address.getNameRoad(), tt.getLocation().street.getTypeOfTAG());
        // insert the part of day in Tag
        if (!photo.getPartOfDay().equals("")) {
            insertSeveralInfoInTags(iCA, photo.getPartOfDay(), tt.getTemporal().partOfDay.getTypeOfTAG(),tt.getTemporal().partOfDay.getSubTypeOfTAG(), weight);
            insertSeveralInvertedIndex(idMultimedia, photo.getPartOfDay(), tt.getTemporal().partOfDay.getTypeOfTAG(),tt.getTemporal().partOfDay.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }

        if (!photo.getLightStatus().equals("")) {
            insertSeveralInfoInTags(iCA, photo.getLightStatus(), tt.getLightStatus(). getTypeOfTAG(),tt.getLightStatus().getSubTypeOfTAG() ,weight);
            insertSeveralInvertedIndex(idMultimedia,photo.getLightStatus(),tt.getLightStatus().getTypeOfTAG(),tt.getLightStatus().getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }
        // insert weekend ou weekday in Tag
        if (cal.get(Calendar.DAY_OF_WEEK) > 1 && cal.get(Calendar.DAY_OF_WEEK) <= 6) {
            insertSeveralInfoInTags(iCA, "Weekday", tt.getTemporal().partOfWeek.getTypeOfTAG(),tt.getTemporal().partOfWeek.getSubTypeOfTAG() ,weight);
            insertSeveralInvertedIndex(idMultimedia, "Weekday", tt.getTemporal().partOfWeek.getTypeOfTAG(),tt.getTemporal().partOfWeek.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        } else {
            insertSeveralInfoInTags(iCA, "Weekeend", tt.getTemporal().partOfWeek.getTypeOfTAG(),tt.getTemporal().partOfWeek.getSubTypeOfTAG() ,weight);
            insertSeveralInvertedIndex(idMultimedia, "Weekend", tt.getTemporal().partOfWeek.getTypeOfTAG(),tt.getTemporal().partOfWeek.getSubTypeOfTAG(), weight, tagIndex.getTimeTag(""));
        }
        
        DAO_Friend df = DAO_Friend.getInstance();
        Vector<String> vsF = df.getNearByFriends(idMultimedia, user.getURLFOAFProfil());
        Vector<String> vsFOF = df.getFriendsOfFriend(idMultimedia, user.getLogin());
        dt.insertFriendsTags(vsFOF, iCA);
        dt.insertFriendsTags(vsF, iCA);
        dii.insertFriendInvertedIndex(vsFOF, idMultimedia);
        dii.insertFriendInvertedIndex(vsF, idMultimedia);
        diei.calculateAndInsertSpatialExpandedIndex(address, photo, idMultimedia);
        try{
            System.out.println("Photo "+photo.getName()+" inserted");
        }catch(Exception e){
        
        }
        return true;
    }

    private void insertSeveralInfoInTags(int iCA, String tagValue, String tagType,String tagSubType, double weight) {
        if (!tagValue.contains("null")) {
           Tag t = new Tag();
           t.setTAG_VALUE(tagValue);
           t.setTAG_TYPE(tagType);
           t.setTAG_SUB_TYPE(tagSubType);
           t.setTAG_ID(dt.insertTAG(t));
           dcah.insertContentAnnotationHasTag(t.getTAG_ID(), iCA, weight);
           
           String[] iis = tagValue.split(" ");            
           if(iis.length>1){
            for(int i=0;i<iis.length;i++) {    
                if(!DAO_TAG.isStopWord(iis[i])){ //Test if is not a stop word (e.g., de)
                    t.setTAG_VALUE(iis[i]);
                    t.setTAG_TYPE(tagType);
                    t.setTAG_SUB_TYPE(tagSubType);
                    t.setTAG_ID(dt.insertTAG(t));
                    dcah.insertContentAnnotationHasTag(t.getTAG_ID(), iCA, weight);
                }
            }
           }
        }
    }

    private void insertSeveralInvertedIndex(int idMultimedia, String tagValue, String tagType,String tagSubType, double weight, String stamp) {
        InvertedIndex iv = new InvertedIndex();
        if (!tagValue.contains("null")) {
            //Insert of the hole tag 
            iv.setTAG_VALUE(tagValue);
            iv.setTAG_TYPE(tagType);
            iv.setTAG_SUB_TYPE(tagSubType);
            iv.setTAG_ID(dii.insertInvertedIndex(iv,stamp));
            diihp.insertInvertedIndexPhoto(iv.getTAG_ID(), idMultimedia, weight);
            
            //Insert of the tag parts
            String[] iis = tagValue.split(" ");            
            if(iis.length>1){
                for(int i=0;i<iis.length;i++) {                     
                    if(!DAO_TAG.isStopWord(iis[i])){ //Test if is not a stop word (e.g., de)
                        iv.setTAG_VALUE(iis[i]);
                        iv.setTAG_TYPE(tagType);
                        iv.setTAG_SUB_TYPE(tagSubType);
                        iv.setTAG_ID(dii.insertInvertedIndex(iv,stamp));
                        diihp.insertInvertedIndexPhoto(iv.getTAG_ID(), idMultimedia, weight);
                    }
                }   
            }
            
        }
//                
//        weight = 1;
//        for (int iTag = 0; iTag < vTag.size(); iTag++) {
//            Tag t = (Tag) vTag.elementAt(iTag);
//            if (!t.getTAG_VALUE().contains("null")) {
//                iv.setTAG_VALUE(tagIndex.getManualTag(t.getTAG_VALUE()));
//                iv.setTAG_TYPE(new Type_Tags().getManuel());
//                iv.setTAG_ID(dii.insertInvertedIndex(iv));
//                diihp.insertInvertedIndexPhoto(iv.getTAG_ID(), idMultimedia, weight);
//            }
//        }
    }
//    public static void main(String[] args ){
//        DAO_Photo dp = DAO_Photo.getInstance();
//        Photo p = new Photo();
//        p.setName("grenoble1");
//        p.setURIPhoto("steamer.grenoble1");
//        Point point = new Point();
//        point.setLatitude(12.3);
//        point.setLongitude(23.4);
//        p.setCoor(point);
//        p.setURIAnnotations("Steamer.Annotation.Grenoble1");
//        Temperature temperature = new Temperature();
//        p.setTemperature(temperature);
//        Weather weather = new Weather();
//        weather.setDescription("description Weather");
//        Address address = new Address();
//        address.setNameCity("Paris");
//        address.setNameCountry("France");
//        address.setNameRoad("Rue1");
//        p.setWeather(weather);
//        p.setDateTime(Timestamp.valueOf("2008-02-05 10:22:34"));
//        p.setPartOfDay("Matin");
//        p.setANNOTATION_VALIDATED(false);
//        p.setSeason("Spring");
//        
//        Vector vTags = new Vector();
//        for (int k=1;k<5;k++){
//            Tag t = new Tag();
//            t.setTAG_VALUE("Tag"+k);
//            
//            vTags.add(t);
//        }
//        p.setTags(vTags);
//
//        Vector vWiki = new Vector(); 
//        Wiki wiki = new Wiki();
//        wiki.setLatitude(-126.49);
//        wiki.setLongitude(45.39);
//        wiki.setTitle("wiki02");
//        wiki.setFeature("place");
//        wiki.setRELATION_TYPE("near");
//        wiki.setWikipediaUrl("org.wiki01");
//        vWiki.add(wiki);
//        
//        p.setNearByWikipediaObject(vWiki);
//        
//        PhotoSender dc =new PhotoSender();
//        //dc.insertPhotos(p, address, 1);
//        
////        System.out.println(collection.getURI());
//    }
}
